<?php
declare (strict_types=1);

namespace app\course\model\base;

use app\common\logic\Attach;
use app\common\model\BaseModel;
use app\common\model\ProductType;
use app\course\model\comment\Comment as CourseComment;
use app\course\model\coupon\Coupon;
use app\course\model\payment\PaymentOrderItem as POI;
use app\promotion\logic\Promotion;
use app\school\model\school\School;
use app\user\model\teacher\Teacher;
use think\model\concern\SoftDelete;
use think\model\relation\BelongsTo;
use think\model\relation\HasMany;
use think\model\relation\HasOne;

/**
 * 定义课程数据模型
 */
class Course extends BaseModel
{
    use SoftDelete;

    /**
     * 表名
     *
     * @var string
     */
    protected $name = 'course';

    /**
     * 设置自动写入时间
     *
     * @var boolean
     */
    protected $autoWriteTimestamp = true;

    protected $append = ['user_price'];

    // protected $globalScope  = ['solo', 'expire'];

    /**
     * 定义字段类型
     *
     * @var array
     */
    protected $type = [
        'id'                   => 'integer',
        'status'               => 'integer',
        'mhm_id'               => 'integer',
        'teacher_id'           => 'integer',
        'fullcategorypath'     => 'array',
        'mhm_fullcategorypath' => 'array',
        'scribing_price'       => 'float',
        'price'                => 'float',
        'vip_price'            => 'float',
        'delete_time'          => 'integer',
        'create_time'          => 'integer',
        'update_time'          => 'integer',
    ];

    protected $json = ['ext_data'];

    protected $type_arr = [
        1 => '点播',
        2 => '直播',
        3 => '面授',
        4 => '班级',
        5 => '点播课时',
    ];

    protected static $typeArr = [
        1 => '点播课',
        2 => '直播课',
        3 => '面授课',
        4 => '班级课',
    ];

    public function getCourseTypeText(): array
    {
        return $this->type_arr;
    }

    public static function getCourseTypeTextByType($type): string
    {
        $arr = self::$typeArr;
        return $arr[$type];
    }

// 获取器

    /**
     *  获取状态显示文字
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-03-14
     *
     * @param $value
     * @param $data
     * @return string
     */
    protected function getCourseTypeTextAttr($value, $data): string
    {
        $text = $this->type_arr;

        return isset($data['course_type']) ? $text[$data['course_type']] : '';
    }

    /**
     * 获取课程的产品信息
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-07-26
     *
     * @param $course
     * @return string [type]                         [description]
     */
    public static function getCourseResourceType($course): string
    {
        $type = [
            1 => 'video',
            2 => 'live',
            3 => 'offline',
            4 => 'classes',
        ];

        if ($course['course_type'] == 2 && $course['course_live_type'] == 2) {
            return 'live_small';
        } else {
            return $type[$course['course_type']] ?? 'public';
        }
    }

    public function getScoreStarAttr($value, $data): float
    {
        return round($data['score_average'] / 20, 1);
    }

    /**
     * 根据用户身份返回价格
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-07-17
     */
    public function getUserPriceAttr($value, $data): float
    {
        return self::getUserPrice($data);
    }

    /**
     * 根据用户返回价格
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-07-17
     */
    public function getMzPriceAttr($value = '', $data): array
    {
        return self::getMzPrice($data);
    }

    /**
     * 获取有效活动信息，订单使用
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date 2021-04-07
     *
     * @param $value [description]
     * @param  [type] $data  [description]
     */
    public function getPositivePromotionAttr($value, $data): array
    {
        return app(Promotion::class)->getProductPositivePromotion($data['course_type'], $data['id']);
    }

    /**
     * 简介格式转换,防止富文本编辑器中有表情等
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-08-21
     *
     * @param $value [description]
     */
    public function setInfoAttr($value): string
    {
        return base64_encode($value);
    }

    /**
     * 简介格式转换,防止富文本编辑器中有表情等
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-08-21
     *
     * @param  $value [description]
     */
    public function getInfoAttr($value)
    {
        if (!$value) {
            return '';
        }
        if ($value === base64_encode((string)base64_decode($value, true))) {
            return base64_decode($value);
        } else {
            return $value;
        }
    }

    /**
     * 获取虚拟销售量
     *
     * @param $value
     * @param $data
     * @return int
     */
    public function getSaleCountAttr($value, $data): int
    {
        $sale_count = $data['sale_count'] + ($data['sale_count_market'] ?? 0);

        return intval($sale_count);
    }

// 查询范围

    /**
     * 设置单卖查询条件
     */
    public function scopeSolo($query, $solo = 1)
    {
        $query->where('solo', $solo);
    }

    /**
     * 设置有效期查询条件
     */
    public function scopeExpire($query)
    {
        $query->whereRaw('term_time = 0 OR term_time < 10000 OR term_time > ' . time() . ' ');
    }

    /**
     * 设置状态查询条件
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-03-14
     *
     * @param     $query
     * @param int $status
     */
    public function scopeStatus($query, int $status = 1)
    {
        $query->where('status', $status);
    }

    /**
     * 设置上架时间查询条件
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-06-30
     */
    public function scopeListingTime($query)
    {
        $query->where('listing_time', '<', time());
    }

    /**
     * Author   亓官雨树<lucky.max@foxmail.com>
     * Date 2020-03-20
     */
    public function scopeUpdateStatus($query, $status = 1)
    {
        $query->where('update_status', $status);
    }

    // 定义综合查询范围
    public function scopeOrderDefault($query)
    {
        $query->order('sale_count DESC, best_sort DESC, view_count DESC, create_time DESC');
    }

    // 定义推荐查询范围
    public function scopeOrderSplendid($query)
    {
        $query->where('is_recommend', 1)->order(['best_sort', 'update_time' => 'DESC']);
    }

    // 定义畅销查询范围
    public function scopeOrderPopular($query)
    {
        $query->order(['sale_count' => 'DESC', 'score_average' => 'DESC']);
    }

    // 定义意向课程排序查询范围
    public function scopeOrderFavorite($query)
    {
        $query->order(['best_sort' => 'DESC', 'sale_count' => 'DESC', 'score_average' => 'DESC']);
    }

    // 定义最新查询范围
    public function scopeOrderLatest($query)
    {
        $query->order('create_time DESC');
    }

    // 定义价格升序查询范围
    public function scopeOrderPriceUp($query)
    {
        $query->order('price');
    }

    // 定义价格降序查询范围
    public function scopeOrderPriceDown($query)
    {
        $query->order('price DESC');
    }

    // 定义免费查询范围
    public function scopeParamFree($query)
    {
        $query->where('price', '<=', '0');
    }

    // 定义会员查询范围
    public function scopeParamVip($query)
    {
        $query->where('vip_price', '>', '0');
    }

    // 定义考试查询范围
    public function scopeParamExam($query)
    {
        // $query->where('price <= 0');
    }

    // 定义试听查询范围
    public function scopeParamAudition($query)
    {
        $query->where('id', 'IN', app(CourseSection::class)->where('is_last', 1)->where('audition', '>', '0')->group('course_id')->column('course_id'));
    }

    // 定义活动查询范围
    public function scopeParamEvent($query)
    {
        $time = time();
        $ids  = app(Promotion::class)
            ->where('status', 1)
            ->where('start_time', '<', $time)
            ->where('end_time', '>', $time)
            ->column('product_id');
        $query->where('id', 'IN', $ids);
    }

    public function scopeClasses($query)
    {
        $query->where('ext_data', '<>', '')->where('ext_data->headmaster', '<>', '');
    }

// 关联

    // 关联课时章节
    public function section(): HasMany
    {
        return $this->hasMany(CourseSection::class, 'course_id');
    }

    // 关联课时章节
    public function sec(): HasOne
    {
        return $this->hasOne(CourseSection::class, 'course_id');
    }

    // 关联课时数量
    public function sectionCount(): HasMany
    {
        return $this->hasMany(CourseSection::class)->where('is_last', 1)->where('status', 1);
    }

    // 关联点评
    public function courseComment(): HasMany
    {
        return $this->hasMany(CourseComment::class);
    }

    // 课程卡
    public function courseCard(): HasOne
    {
        return $this->hasOne(Coupon::class, 'course_id');
    }

    // 关联机构名称
    public function school(): BelongsTo
    {
        return $this->belongsTo(School::class, 'mhm_id')->bind(['school_name' => 'title'])->removeOption('soft_delete');
    }

    // 课程封面
    public function coverUrl(): BelongsTo
    {
        return $this->belongsTo(Attach::class, 'cover', 'id')->bind(['cover_url' => 'fileurl']);
    }

    // 关联卡券数量
    public function couponCount(): BelongsTo
    {
        return $this->belongsTo(School::class, 'mhm_id')->withCount(['coupon_count' => 'coupon_count'])->bind(['coupon_count']);
    }

    public function student(): HasMany
    {
        return $this->hasMany(CourseStudent::class);
    }

    public function stu(): HasOne
    {
        return $this->hasOne(CourseStudent::class);
    }

    public function teacherName(): BelongsTo
    {
        return $this->belongsTo(Teacher::class, 'teacher_id')->with(['teacher_name'])->bind(['teacher_name' => 'title']);
    }

    public function teacherAvatar(): BelongsTo
    {
        return $this->belongsTo(Teacher::class, 'teacher_id')->with(['teacher_avatar'])->bind(['teacher_avatar' => 'avatar']);
    }

    public function orderItem(): HasMany
    {
        return $this->hasMany(POI::class, 'product_id')->where('product_type_id', 'IN', '1,2,3,4');
    }

    /**
     * 关联课程考试
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date 2021-09-26
     *
     * @return HasMany [type] [description]
     */
    public function exam(): HasMany
    {
        return $this->hasMany(CourseExamLink::class, 'course_id')
            ->field('course_id,paper_id')
            ->with(['paper_base'])
            ->hidden(['course_id']);
    }

    /**
     * 获取所有课程产品类型
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-07-30
     *
     * @return array [type]                         [description]
     */
    public static function getCourseProducts(): array
    {
        return [
            ProductType::getProductIdByKey('video'),
            ProductType::getProductIdByKey('live'),
            ProductType::getProductIdByKey('offline'),
            ProductType::getProductIdByKey('classes'),
        ];
    }

    /**
     * 根据课程类型获取产品ID
     * Author   Martinsun<syh@sunyonghong.com>
     * Date 2020-07-30
     *
     * @param    [type]                         $course_type [description]
     * @return int|mixed [type]                                      [description]
     */
    public static function getProductIdByCourseType($course_type)
    {
        $products = [
            1 => ProductType::getProductIdByKey('video'),
            2 => ProductType::getProductIdByKey('live'),
            3 => ProductType::getProductIdByKey('offline'),
            4 => ProductType::getProductIdByKey('classes'),
        ];
        return $products[$course_type] ?? 0;
    }
}
